<template>
  <!-- 弹窗对话框，根据mode的不同显示不同的标题，支持新增、编辑和查看操作 -->
  <t-drawer
    :visible="dialogVisible"
    :header="mode == 'new' ? '新增' : mode == 'edit' ? '编辑' : mode == 'view' ? '查看' : ''"
    @confirm="handleSubmit"
    :confirmBtn="EDIT_FORM_SAVE_BUTTON(mode)"
    @cancel="handleClose"
    @close="handleClose"
    size="55%"
  >
    <t-form ref="formInstance" :data="pageData.formData" :rules="pageData.formRules" :disabled="pageData.readOnly">
      <t-form-item label="菜单名称" name="name">
        <t-input v-if="!pageData.readOnly" v-model="pageData.formData.name" />
        <div v-else class="form__text">{{ pageData.formData.name }}</div>
      </t-form-item>
      <t-form-item label="菜单代号" name="code">
        <t-input
          v-if="!pageData.readOnly"
          v-model="pageData.formData.code"
          placeholder="应与前端路由页面的 name 保持一致。"
        />
        <div v-else class="form__text">{{ pageData.formData.code }}</div>
      </t-form-item>
      <t-form-item label="PC 端图标" name="pcIcon">
        <t-input
          v-if="!pageData.readOnly"
          v-model="pageData.formData.pcIcon"
          placeholder="请从 TDesign 图标库中选取图标值"
        />
        <div v-else class="form__text">
          <t-icon :name="pageData.formData.code" />&nbsp; - {{ pageData.formData.code }}
        </div>
      </t-form-item>
      <t-form-item
        label="PC 端路由"
        name="pcRoute"
        help="PC 端根据路由名（菜单代号）进行路由跳转，路由地址仅作记录，可不填。"
      >
        <t-input v-if="!pageData.readOnly" v-model="pageData.formData.pcRoute" placeholder="顶级菜单不需要填写路由。" />
        <div v-else class="form__text">{{ pageData.formData.pcRoute }}</div>
      </t-form-item>
      <t-form-item label="优先级" name="sort">
        <t-input-number
          :min="0"
          v-if="!pageData.readOnly"
          style="width: 100%"
          v-model="pageData.formData.sort"
          :decimalPlaces="0"
          theme="column"
        />
        <div v-else class="form__text">{{ pageData.formData.sort }}</div>
      </t-form-item>
      <!-- <t-form-item label="移动端图标" name="mobileIcon">
        <t-input v-model="pageData.formData.mobileIcon" />
      </t-form-item>
      <t-form-item label="移动端路由" name="mobileRoute">
        <t-input v-model="pageData.formData.mobileRoute" placeholder="顶级菜单不需要填写路由。" />
      </t-form-item> -->
      <t-form-item label="父级菜单" name="parentName">
        <div v-if="!pageData.readOnly" style="display: flex; width: 100%">
          <InputSelect v-model="pageData.formData.parentMenuName" @onClick="pageData.menu.show = true" />
          <t-button theme="danger" style="margin-left: 6px" @click="handleClearParentId">清除父菜单</t-button>
        </div>
        <div v-else class="form__text">{{ pageData.formData.parentMenuName }}</div>
      </t-form-item>
      <!-- <t-form-item
        label="查看权限"
        name="roleIds"
        help="请确保：父级菜单需包含其所有子级菜单的权限设置；顶级菜单必须涵盖下级所有菜单的权限，否则相关菜单将不可见。"
      >
        <t-select v-model="pageData.formData.roleIds" multiple>
          <t-option
            v-for="item in pageData.roleSelectData"
            :key="item"
            :label="`${item.roleName}（${item.id}）`"
            :value="item.id"
          ></t-option>
        </t-select>
      </t-form-item> -->
      <t-form-item label="菜单状态" name="status">
        <t-select v-model="pageData.formData.status">
          <t-option v-for="item in STATUS_DATA" :key="item" :label="item.label" :value="item.value"></t-option>
        </t-select>
      </t-form-item>
      <t-form-item label="备注" name="remark">
        <t-textarea v-if="!pageData.readOnly" v-model="pageData.formData.remark" />
        <div v-else class="form__text">{{ pageData.formData.remark }}</div>
      </t-form-item>
    </t-form>
  </t-drawer>
  <SelectTable
    v-if="pageData.menu.show"
    :loading="false"
    :showDialog="pageData.menu.show"
    mode="tree"
    width="60%"
    rowSelectionType="single"
    :tableData="pageData.menu.data"
    :columns="pageData.menu.columns"
    @onConfirm="handleMenuSelectConfirm"
    @onCancel="handleMenuSelectClose"
  />
</template>

<script lang="tsx" setup>
// 框架和组件库
import { reactive, ref, toRaw } from "vue";
import { MessagePlugin, type FormInstanceFunctions } from "tdesign-vue-next";

// TS 类型文件
import type { ISelectTableGroupsNoPage } from "@/types";

// 工具函数
import { http } from "@/utils/fetch";

// 常量
import { EDIT_FORM_SAVE_BUTTON } from "@/common/constants";
import { STATUS_DATA } from "@/common/constants";

// 业务数据
import { useUserStore } from "@/stores/modules/user";

const props = defineProps({
  id: {
    type: String,
    required: true
  },
  dialogVisible: {
    type: Boolean,
    default: false
  },
  mode: {
    type: String,
    required: true
  }
});

const emits = defineEmits(["close"]);

const formInstance = ref<FormInstanceFunctions | null>(null);

const GET_FORM_PATH = "/menu/findOne"; // 查询接口
const CREATE_FORM_PATH = "/menu/create"; // 创建接口
const UPDATE_FORM_PATH = "/menu/update"; // 更新接口

const userStore = useUserStore();

const pageData = reactive({
  readOnly: false,
  formData: {
    id: "",
    createdTime: "",
    updatedTime: "",
    createdBy: "",
    updatedBy: "",
    remark: "",
    name: "",
    code: "",
    pcIcon: "",
    sort: 0,
    status: 0,
    parentMenu: {},
    parentMenuId: null,
    parentMenuName: "",
    hasDeleted: 0,
    pcRoute: ""
  },
  menu: {
    show: false,
    data: [],
    columns: [
      {
        colKey: "name",
        title: "菜单名称",
        fixed: "left"
      },
      {
        colKey: "code",
        title: "菜单代号"
      },
      {
        colKey: "sort",
        title: "优先级"
      },
      {
        colKey: "statusLabel",
        title: "状态"
      }
    ]
  } as ISelectTableGroupsNoPage,
  formRules: {
    name: [
      {
        required: true,
        message: "请输入菜单名称",
        type: "error",
        trigger: "blur"
      }
    ],
    code: [
      {
        required: true,
        message: "请输入菜单代号",
        type: "error",
        trigger: "blur"
      }
    ]
  }
});

/**
 * 初始化表单数据。
 * 根据不同的操作模式（新增、编辑、查看），加载不同的数据。
 * @param id - ID，用于编辑和查看模式下查询信息。
 */
const initFormData = async (id = "") => {
  if (props.mode === "new") {
    // 新增模式下，初始化表单ID和创建时间
    pageData.formData.createdBy = userStore.userData?.id;
    pageData.formData.createdTime = new Date().toISOString();
  } else if (props.mode === "edit" || props.mode === "view") {
    const resultData = await http("GET", `${GET_FORM_PATH}?id=${encodeURIComponent(id)}`);
    pageData.formData = resultData.data;
    pageData.formData.parentMenuName = resultData.data.parentMenu.name;
  }
};

/**
 * 初始化选择表格数据。
 * 查询所有角色信息，用于选择下拉框。
 */
// const initRoleSelectData = async () => {
//   const resultData = await http("POST", "/user/role/findAll", {});
//   pageData.roleSelectData = resultData.data;
// };

/**
 * 回查菜单列表数据。
 * 查询所有菜单信息，用于选择表格。
 */
const initMenuSelectData = async () => {
  const resultData = await http("GET", "/menu/findAll");
  pageData.menu.data = resultData.data;
};

/**
 * 对话框确认时候的操作
 * @param e 选中的菜单数据
 */
const handleMenuSelectConfirm = (e: Record<string, any>) => {
  if (props.mode == "view") {
    MessagePlugin.error("查看模式下不能选择数据。");
    return;
  }

  pageData.formData.parentMenuId = e.options.currentRowData.id;
  pageData.formData.parentMenuName = e.options.currentRowData.name;
  pageData.menu.show = false;
};

const handleClearParentId = () => {
  pageData.formData.parentMenuId = null;
  pageData.formData.parentMenuName = "";
};
/**
 * 关闭选择表格。
 */
const handleMenuSelectClose = () => {
  pageData.menu.show = false;
};

/**
 * 提交表单。
 * 根据不同的操作模式（新增、编辑），调用不同的接口保存信息。
 */
const handleSubmit = async () => {
  const validateResult = await formInstance?.value?.validate();

  /* validateResult 在校验没通过的时候返回的是一个 Object，校验通过的时候返回的是
   * 布尔值 true，所以这里写死判断为 true。
   */
  if (validateResult !== true) {
    return;
  }
  let resultData;

  if (props.mode === "view") {
    handleClose();
  }

  const postFormData: Record<string, any> = structuredClone(toRaw(pageData.formData));

  if (props.mode === "new") {
    // 新增
    resultData = await http("POST", CREATE_FORM_PATH, postFormData);
  } else {
    // 更新
    postFormData.updatedTime = new Date().toISOString();
    postFormData.updatedBy = userStore.userData?.id;

    resultData = await http("POST", UPDATE_FORM_PATH, postFormData);
  }

  // 根据接口返回结果，提示操作成功或失败，并关闭对话框
  if (resultData.code === 200) {
    emits("close", "success");
  }
};

const handleClose = () => {
  // 关闭对话框，并返回取消操作标识
  emits("close", "cancel");
};

// 如果是查看模式，设置表单为只读
if (props.mode == "view") {
  pageData.readOnly = true;
}

// 初始化表单数据，根据传入的 ID
initFormData(props.id);
// initRoleSelectData();
initMenuSelectData();
</script>
